package com.example.spring_gobang.api;

import com.example.spring_gobang.common.AppVariable;
import com.example.spring_gobang.messgae.MatchRequest;
import com.example.spring_gobang.messgae.MatchResponse;
import com.example.spring_gobang.game.Matcher;
import com.example.spring_gobang.game.OnlineUserManage;
import com.example.spring_gobang.model.UserInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@Component
public class Match extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private OnlineUserManage manage;
    @Autowired
    private Matcher matcher;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //玩家上线 加入到队列中
        //在登录的时候创建了一个会话信息
        //然后在WebSocketConfig中把会话给了WebSocket协议
        //然后通过getAttributes方法就可以获取这个会话的键值对
        try {
            //可能会拿到一个空对象
            UserInfo userInfo = (UserInfo) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
            //防止出现多开问题
            WebSocketSession tmpSession = manage.getFromById(userInfo.getUserId());
            if (tmpSession != null){
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setReason("账号已经登录！");
                response.setMessage("repeatConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                //这里需要注意的是close方法会触发afterConnectionClosed方法
                //那么它就可能会把最初登录的那个给搞下线了
//                session.close(); 直接关闭过去绝对
                //换一种更加合理地方式

                return;
            }
            manage.enterGameHall(userInfo.getUserId(),session);
            System.out.println("玩家" + userInfo.getUsername() +"游戏大厅！");
        } catch (NullPointerException e) {
            e.printStackTrace();
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("您尚未登录！无法进行匹配");
            //先通过objectMapper把字符串转换成JSON格式，然后再用TextMeasage包装一下
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        UserInfo userInfo = (UserInfo) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
        //获取客户端发来的数据
        String payload = message.getPayload();
        //把前端发来的JSON格式的字符串转成Java对象中的MatchRequest
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")){
            //进入匹配队列
            matcher.add(userInfo);
            //给客户端发送一个消息表示已经进入匹配队列
            response.setOk(true);
            response.setMessage("startMatch");
        }else if (request.getMessage().equals("stopMatch")){
            matcher.remove(userInfo);
            response.setOk(true);
            response.setMessage("stopMatch");
        }else {
            response.setOk(false);
            response.setMessage("非法请求匹配！");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            //玩家出现异常下线
            UserInfo userInfo = (UserInfo) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
            WebSocketSession tmpSession = manage.getFromById(userInfo.getUserId());
            if (tmpSession == session){
                manage.exitGameHall(userInfo.getUserId());
            }
            //如果玩家正在匹配中链接出现异常 就要移除匹配队列
            matcher.remove(userInfo);
        } catch (NullPointerException e) {
            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录！无法进行匹配");
//            //先通过objectMapper把字符串转换成JSON格式，然后再用TextMeasage包装一下
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            //玩家正常下线
            UserInfo userInfo = (UserInfo) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
            WebSocketSession tmpSession = manage.getFromById(userInfo.getUserId());
            if (tmpSession == session){
                manage.exitGameHall(userInfo.getUserId());
            }
            //如果正在匹配中连接断开了 则需要从匹配队列中移除
            matcher.remove(userInfo);
        } catch (NullPointerException e) {
            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录！无法进行匹配");
//            //先通过objectMapper把字符串转换成JSON格式，然后再用TextMeasage包装一下
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}
